import numpy as np


def lsa_by_svd(X, k):
    """利用矩阵奇异值分解的潜在语义分析

    :param X: 单词文本矩阵
    :param x: 目标话题数量
    :return: 话题向量空间, 文本集合在话题向量空间的表示
    """
    U, S, V = np.linalg.svd(X)  # 奇异值分解
    U = U[:, :k]
    S = np.diag(S[:k])
    V = V[:k, :]

    return U, np.dot(S, V)


if __name__ == "__main__":
    X = [[0, 0, 1, 1, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 1, 0, 0, 1],
         [0, 1, 0, 0, 0, 0, 0, 1, 0],
         [0, 0, 0, 0, 0, 0, 1, 0, 1],
         [1, 0, 0, 0, 0, 1, 0, 0, 0],
         [1, 1, 1, 1, 1, 1, 1, 1, 1],
         [1, 0, 1, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 1, 0, 1],
         [0, 0, 0, 0, 0, 2, 0, 0, 1],
         [1, 0, 1, 0, 0, 0, 0, 1, 0],
         [0, 0, 0, 1, 1, 0, 0, 0, 0]]

    np.set_printoptions(precision=2, suppress=True)
    U, SV = lsa_by_svd(X, 3)

    print(U)
    # [[-0.15  0.27 -0.04]
    #  [-0.24 -0.38  0.09]
    #  [-0.13  0.17 -0.07]
    #  [-0.18 -0.19 -0.45]
    #  [-0.22 -0.09  0.46]
    #  [-0.74  0.21 -0.21]
    #  [-0.18  0.3   0.28]
    #  [-0.18 -0.19 -0.45]
    #  [-0.36 -0.59  0.34]
    #  [-0.25  0.42  0.28]
    #  [-0.12  0.14 -0.23]]

    print(SV)
    # [[-1.38 -0.87 -1.32 -1.02 -0.86 -1.92 -1.11 -1.12 -1.71]
    #  [ 0.84  0.39  1.19  0.62  0.35 -1.43 -0.18  0.8  -1.14]
    #  [ 0.82 -0.28  0.31 -0.49 -0.45  1.02 -1.1   0.   -0.67]]
